gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/example/ActiveX/MsAgentDemo/MsAgentDemo.cpp
/********************************************************************** // // // ########## ###### ######### # ###### # // ############# ########### ######### ######### ### // ######## # ### ## ############# ## ## ##### # #### // #### ## ## ### ### ### # # ##### ##### // # ### # # ## ## ## ## ### // ## ###### ## ## #### #### # # ## // ######### ### ## ### ####### ###### ## ## ### // ###### ## ###### ## ## #### # ## #### // ####### ## ###### ## ### ## ## ### ###### // ######### ## ###### ## ###### ### ## ### # ##### // ## ###### ####### ### #### ## ## ####### ######## ## #### // ## #### ### # ### ### ## ########## ###### ## #### // ## ## ## ######### #### # ## // # ### // ## // ### // ## // // // RingSDK演示程序 //作者:临风 // //版本:1.0 // //声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到 // 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在 // 修改的同时给作者一份同样的副本。 // 本类库不得用于任何商业用途,如确实需要,请与作者联系。 // //e-mail:ringphone@sina.com // //原文件名:msagentdemo.cpp // //说明:演示对ActiveX控件MsAgent(助手)的调用。 // *********************************************************************/ #include "ringcontainer.h" //#import "C:\WINNT.0\msagent\agentctl.dll" //利用上面的import编译后就会产生tlh和tlb文件,以后只要include tlh就可以, //否则每次编译都会重新生成tlh和tlb文件。 #include "agentctl.tlh" using namespace AgentObjects; BEGIN_SETUPMAINWINDOW(IS_WINDOW) //需要支持ActiveX,必须声明BEGIN_DEF_OCXPTR, //该宏实现了CreateContainer函数(创建ActiveX容器) BEGIN_DEF_OCXPTR DEFCONTAINER(AgentCon); RINGOCXPTR(IAgentCtlEx) gAgent; IAgentCtlCharactersPtr pChars; IAgentCtlCharacterExPtr pMerlin; IAgentCtlRequestPtr pRequest; IConnectionPoint *pCP; IUnknown *pSinkUnk; DWORD dwCookie; END_DEF_OCXPTR BEGIN_DEFMSG DEFMSG(WM_CREATE) DEFMSG(WM_CLOSE) END_DEFMAINMSG END_SETUPMAINWINDOW BEGIN_REGMAINMSG REGMSG(WM_CREATE) REGMSG(WM_CLOSE) END_REGMSG //助手事件处理类 class CSink : public IDispatch { public: // 构造/析构函数 CSink():m_uRef(0){} virtual ~CSink() {} // IUnknown接口实现 STDMETHODIMP QueryInterface( REFIID iid, void **ppvObject ) { if ( iid == __uuidof( _AgentEvents ) ) { *ppvObject = (_AgentEvents *)this; AddRef(); return S_OK; } if ( iid == IID_IUnknown ) { *ppvObject = (IUnknown *)this; AddRef(); return S_OK; } return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { m_uRef++; return m_uRef; } ULONG STDMETHODCALLTYPE Release() { ULONG u = m_uRef--; if ( 0 == m_uRef ) { delete this; } return u; } // IDispatch接口实现 STDMETHODIMP GetTypeInfoCount( UINT *pctinfo ) { return E_NOTIMPL; } STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { return E_NOTIMPL; } STDMETHODIMP GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { return E_NOTIMPL; } STDMETHODIMP Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags, DISPPARAMS *pDispParams,VARIANT *pVarResult, EXCEPINFO *pExcepInfo,UINT *puArgErr) { HRESULT hr = S_OK; if ( NULL != pDispParams) { if(7 == dispIdMember && 2 == pDispParams->cArgs) { if(VT_I2 == pDispParams->rgvarg[0].vt && VT_BSTR == pDispParams->rgvarg[1].vt) { OnHide( pDispParams->rgvarg[1].bstrVal, pDispParams->rgvarg[0].iVal ); } else // 类型错误 { hr = DISP_E_TYPEMISMATCH; } } else if(dispIdMember == 6) { if(pDispParams->cArgs == 5) OnDragComplete(pDispParams->rgvarg[4].bstrVal, pDispParams->rgvarg[3].iVal, pDispParams->rgvarg[2].iVal, pDispParams->rgvarg[1].iVal, pDispParams->rgvarg[0].iVal); } else // 参数个数错误 { hr = DISP_E_BADPARAMCOUNT; } } return hr; } // 要处理的_AgentEvents事件 STDMETHODIMP OnHide( _bstr_t CharacterID, short Cause ) { PostMessage(GetMainWnd(),WM_CLOSE,0,0); return S_OK; } STDMETHODIMP OnDragComplete(_bstr_t CharacterID,short Button,short Shift,short x,short y) { window->pMerlin->Speak(CComVariant("轻点,轻点,别乱扔。")); return S_OK; } private: ULONG m_uRef; }; int RingMain() { InitRingContainer(); APP_CREATEWINDOW("MsAgentDemo","RINGSDK_COMAGENTCLASS",WS_OVERLAPPEDWINDOW,(LPSTR)NULL); RingApp.Run(FALSE); return FreeRingContainer(); } RINGMAINMSG(WM_CREATE) { //创建包容器 if(CreateContainer(AgentCon,OLESTR("{D45FD31B-5C6E-11D1-9EC1-00C04FD7081F}"),0)) { HRESULT hr = AgentCon.QueryControl(__uuidof(IAgentCtlEx),(void**)&gAgent); if(SUCCEEDED(hr)) { pCP = NULL; pSinkUnk = NULL; dwCookie = 0; // 获取角色文件路径 TCHAR szPath[MAX_PATH]; GetWindowsDirectory( szPath, MAX_PATH ); lstrcat(szPath, _T("\\msagent\\chars\\merlin.acs")); // 进行连接 gAgent->PutConnected((VARIANT_BOOL)-1); // 设置连接点的过程开始 IConnectionPointContainer *pCPC = NULL; // 查询连接点容器 hr = gAgent->QueryInterface( IID_IConnectionPointContainer, (void **)&pCPC ); if ( FAILED( hr ) ) { Errmsg("查询连接点容器失败!"); return 0; } // 查找连接点 hr = pCPC->FindConnectionPoint(__uuidof(_AgentEvents),&pCP); if(FAILED(hr)) { Errmsg("查找连接点失败!"); return 0; } // 这时连接点容器已经没用了,释放之 pCPC->Release(); pCPC = NULL; // 创建通知对象 CSink* pSink = new CSink; hr = pSink->QueryInterface(IID_IUnknown,(void **)&pSinkUnk); if(FAILED(hr)) { Errmsg("接口查询失败!"); return 0; } // 对连接点进行设置 hr = pCP->Advise(pSinkUnk,&dwCookie); if ( FAILED( hr ) ) { Errmsg("连接点设置失败!"); return 0; } // 获得角色列表 pChars = gAgent->GetCharacters(); // 装载角色 pRequest = pChars->Load( _bstr_t("merlin"), CComVariant(szPath) ); pMerlin = pChars->Character( _bstr_t("merlin") ); //pMerlin->put_AutoPopupMenu((VARIANT_BOOL)0); // 显示角色 pMerlin->Show(); // 计算屏幕中央坐标,并移动 short x = ( GetSystemMetrics( SM_CXFULLSCREEN ) - pMerlin->GetWidth() ) / 2; short y = ( GetSystemMetrics( SM_CYFULLSCREEN ) - pMerlin->GetHeight() ) / 2; pRequest = pMerlin->MoveTo( x, y ); pRequest = pMerlin->Speak( CComVariant("右键单击我,选择“隐藏”以结束程序。") ); } } return 0; } RINGMAINMSG(WM_CLOSE) { pCP->Unadvise(dwCookie); pCP->Release(); // 由于pSinkUnk进行了QueryInterface,所以必须Release之 pSinkUnk->Release(); DestroyWindow(m_hWnd); return Quit(); }